#pragma once
#include "iStateHandler.h"

namespace _FOGGE_
{
	namespace _UTIL_
	{
		namespace _FSM_
		{
			template<class T>
			class aStateHandler abstract:
				public iStateHandler
			{
			public:

				/*!
					state event handler member function type
				*/
				typedef  void ((T::*STATE_EVENT_HANDLER_FUNC)) (void);


				/*implemetation of interface*/
				void OnSubStateEvent(StateUnit* pstate,foUInt event_ID)
				{
					StateEventMap::iterator iter_state= m_StateEventMap.find(pstate);

					if(iter_state!=m_StateEventMap.end())
					{
						StateEventVector* pSEV= iter_state->second;

						if(event_ID>=pSEV->size());
						{
							assert(!"invalid sub event id");
						}
							

						//if exist,call substateevent handler
						if(pSEV->at(event_ID))
							(boost::polymorphic_downcast<T*>(this)->*pSEV->at(event_ID))();
					}

					
					
				}

			protected:
				aStateHandler(void)
				{
				}
				~aStateHandler(void)
				{
					StateEventMap::iterator iter_state= m_StateEventMap.begin();
					StateEventMap::iterator end= m_StateEventMap.end();

					for(;iter_state != end;++iter_state)
					{
						StateEventVector* pSEV=iter_state->second;

						foDELETE( pSEV );
					}

					m_StateEventMap.clear();

				}
				void RegisterSubStateEventHandler(StateUnit* pstateunit,UINT event_ID,STATE_EVENT_HANDLER_FUNC punc)
				{
					StateEventMap::iterator iter_state= m_StateEventMap.find(pstateunit);

					StateEventVector* pSEV=NULL;
					if(iter_state==m_StateEventMap.end())
					{//insert new pair
						pSEV= foNEW StateEventVector;
						m_StateEventMap[pstateunit]=pSEV;
					}
					else
					{
						pSEV= iter_state->second;
					}

					if(pSEV->size()<event_ID+1)
					{

						pSEV->resize(event_ID+1);
					}

					pSEV->at(event_ID)=punc;
				}

			private:
				typedef std::vector<STATE_EVENT_HANDLER_FUNC> StateEventVector;

				typedef std::map<StateUnit*,StateEventVector*> StateEventMap;

				StateEventMap m_StateEventMap;

			};
		}
	}
}
